home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Periodicals / develop / develop 3 code / Accessing CD-ROM Audio / CDA.text < prev   
Encoding:
Text File  |  1990-06-06  |  28.2 KB  |  890 lines  |  [TEXT/pdos]

  1.          lst   off
  2.  
  3. ******************************************************************************
  4. *                                                                            *
  5. * CD Remote CDA  ------------------------------------  v1.2 - June 5th, 1990 *
  6. * by Eric C. Mueller, 2760 Roundtop Dr., Col. Springs, CO 80918 719-548-8295 *
  7. *                                                                            *
  8. * >> Use apple-6 to assemble, link, and save the CDA file to disk            *
  9. *                                                                            *
  10. ******************************************************************************
  11.  
  12.          xc               ;allow 65c02 opcodes
  13.          xc               ;allow 65c816 opcodes
  14.          mx    %00        ;full 16 bit code
  15.          cas   in         ;case insensitive
  16.          rel              ;relocatable
  17.          typ   cda        ;filetype = CDA
  18.          dsk   cda.l      ;object file is cda.l
  19.          use   cda.macs   ;use this macro file
  20.  
  21. *=============================================================================
  22.  
  23.          do    0          ;turn off assembly for macro defintions
  24. dl       mac              ;define long - same as ADRL
  25.          adrl  ]1
  26.          <<<
  27.          fin              ;turn assembly back on
  28.  
  29. *=============================================================================
  30. * CDA header
  31.  
  32.          str   'CD Remote v1.2' ;title
  33.          adrl  StartUp
  34.          adrl  ShutDown
  35.  
  36. *=============================================================================
  37. * Equates
  38.  
  39. DInfo    equ   $202C      ;GS/OS calls
  40. DStatus  equ   $202D
  41. DControl equ   $202E
  42.  
  43. ResetDevice equ $0000     ;generic SCSI call
  44.  
  45. ReadTOC  equ   $80c1      ;SCSI CD ROM-specific calls
  46. ReadQSubcode equ $80c2
  47.  
  48. AudioSearch equ $80c8
  49. AudioPlay equ  $80c9
  50. AudioPause equ $80ca
  51. AudioStop equ  $80cb
  52. AudioStatus equ $80cc
  53. AudioScan equ  $80cd
  54.  
  55. GSOS     equ   $e100a8    ;GS/OS entry point
  56. OS_Kind  equ   $e100bc    ;boolean: is GS/OS the current OS?
  57.  
  58.          dum   1          ;set up dummy equates for direct page
  59. dpage                     ;start of direct page
  60.  
  61. temp     dl    0          ;temp variable
  62. GDSstatus dw   0          ;result of GetDeviceStatus cal
  63. maxTrack dw    0          ;max track available on this disc
  64. pauseFlag dw   0          ;flag: is disc currently in pause?
  65. suTT     dw    0          ;flag: did we start up the text tools?
  66. newDiscFlag dw 0          ;boolean: new disc inserted?
  67. endTicks dl    0          ;tick count (for waiting one second)
  68. iANDmsk  dw    0          ;input text device AND mask
  69. iORmsk   dw    0          ;input text device OR mask
  70. oANDmsk  dw    0          ;output text device AND mask
  71. oORmsk   dw    0          ;output text device OR mask
  72. iDevType dw    0          ;input text device type
  73. iPtrOrSlot dw  0          ;input text device slot (or ptr)
  74. oDevType dw    0          ;output text device type
  75. oPtrOrSlot dw  0          ;output text device slot (or ptr)
  76.  
  77. dend                      ;end of direct page
  78.          dend             ;end of dummy equates
  79.  
  80. *=============================================================================
  81. * Program
  82.  
  83. StartUp
  84.          phb              ;save old data bank register
  85.  
  86.          phk              ;set data bank to pgm. bank
  87.          plb
  88.  
  89.          tdc              ;save old direct page ptr
  90.          sta   oldDP
  91.  
  92.          tsc
  93.          sec              ;allocate direct page space
  94.          sbc   #dend-dpage
  95.          tcs              ;set stack and dpage
  96.          tcd
  97.  
  98.          jsr   Start      ;get the appropriate tools ready
  99.  
  100.          shortacc         ;short accumulator
  101.          ldal  OS_Kind    ;check OS byte - can't make GS/OS calls from P8!
  102.          longacc
  103.          beq   p8         ;in P8: sorry, we're outta here...
  104.  
  105.          jsr   Main       ;do the main loop
  106.  
  107. end
  108.          lda   suTT       ;did we start up the text tools?
  109.          beq   :no        ;no (see below)
  110.          _TextShutDown    ;yes, so get rid of them
  111.          bra   :cont      ;and continue
  112.  
  113. :no                       ;no, we just used the text tools, so we have to...
  114.          jsr   RestoreTDevs ;...restore the text devices to what they were
  115.  
  116. :cont    tsc              ;fix up the stack (get rid of our dpage)
  117.          clc
  118.          adc   #dend-dpage
  119.          tcs
  120.          lda   oldDP      ;restore old DP
  121.          tcd
  122.  
  123.          plb              ;restore old data bank register
  124.  
  125. ShutDown
  126.          rtl              ;and leave
  127.  
  128. p8
  129.          ~WriteCString #:proDOS
  130.          jsr   getKey
  131.          bra   end
  132.  
  133. :proDOS  asc   0d0d0d'Sorry - this CDA requires GS/OS to operate. '00
  134.  
  135. *=============================================================================
  136. * Main loop
  137.  
  138. Main
  139.          stz   newDiscFlag
  140.          ~WriteCString #Title ;print title info
  141.          jsr   FindCDRom  ;find the CD-ROM drive
  142.          bcs   :exit      ;exit if none found
  143.  
  144. :newDisc
  145.          jsr   NewDisc    ;set up for new disc
  146.  
  147. :1
  148.          jsr   GDS        ;get device status
  149.          and   #%1_0000   ;check disc-in-drive bit
  150.          beq   :noDisc    ;none! don't do anything, now
  151.  
  152.          lda   newDiscFlag ;check the disc-switched flag
  153.          bne   :newDisc   ;there was a new disc inserted! get it
  154.  
  155.          jsr   ZeroParamList ;zap old parameter list
  156.          lda   #5         ;return five bytes, please
  157.          sta   DSrequest
  158.          lda   #ReadQSubcode ;find out the current Q subcode info
  159.          jsr   DoDStatus
  160.  
  161.          lda   #0         ;clear out high byte of accum
  162.          shortacc
  163.          lda   buffer+1   ;get track number
  164.          longacc
  165.          sta   TIBCD      ;store track # in BCD
  166.          jsr   BCD2ASCII
  167.          xba
  168.          sta   TrackInd   ;store track number
  169.          shortacc
  170.          lda   buffer+3   ;get minutes value
  171.          longacc
  172.          jsr   BCD2ASCII  ;convert it
  173.          xba
  174.          sta   Minutes
  175.          shortacc
  176.          lda   buffer+4   ;get seconds value
  177.          longacc
  178.          jsr   BCD2ASCII  ;convert it
  179.          xba
  180.          sta   Seconds
  181.  
  182.          jsr   Events     ;do our li'l event loop
  183.          bcc   :1         ;quit not picked, keep going
  184.  
  185. :exit
  186.          rts              ;we're outta here
  187.  
  188. :noDisc
  189.          ~WriteCString #:discGone
  190.          jsr   getKey
  191.          cmp   #$001b     ;ESC pressed?
  192.          beq   :exit      ;yes - leave now
  193.          jsr   GDS        ;no - get status again...
  194.          bra   :1         ;...and work with it
  195.  
  196. :discGone asc  0d0d'Please insert a disc and press return, or ESC to exit. '00
  197.  
  198. Title    asc   'CD ROM REMOTE v1.2, by Eric C. Mueller'0d
  199.          asc   'See develop #3. Copyright, 1990.'0d0d00
  200.  
  201. * get device status - quick 'n dirty
  202.  
  203. GDS                       ;
  204.          jsr   ZeroParamList ;zap old parameter list
  205.          lda   #$0002     ;get just the status word (two bytes)
  206.          sta   DSrequest
  207.          lda   #$0000     ;GetDeviceStatus (not device-specific)
  208.          sta   DScode     ;store control code
  209.          jsl   GSOS
  210.          dw    DStatus    ;make GS/OS DStatus call
  211.          adrl  statParm
  212.          lda   statusList ;get status word
  213.          sta   GDSstatus  ;hold status here
  214.          pha
  215.          and   #1         ;check disc-switched bit
  216.          ora   newDiscFlag ;keep old flag, if set
  217.          sta   newDiscFlag ;save status
  218.          pla
  219.          stz   statusList ;(zero parm table for CD-ROM audio calls)
  220.          rts
  221.  
  222. *=============================================================================
  223. * Display prompt, get key press, handle it, return
  224.  
  225. Events
  226.          ~WriteCString #prompt ;print the prompt
  227. :0       jsr   getKey     ;get a keypress
  228.  
  229.          cmp   #$0060     ;is it lowercase?
  230.          blt   :1         ;no
  231.          and   #$00df     ;yes - convert to uppercase
  232. :1
  233.  
  234.          ldy   #0         ;start at the top of the table
  235. :2       cmp   commands,y ;is this the key pressed?
  236.          beq   :match     ;yes!
  237.          iny              ;no - move past key
  238.          iny
  239.          iny              ;and past address
  240.          iny
  241.          cpy   #endcommands-commands ;at the end of the table?
  242.          bne   :2         ;no - keep looking
  243.          beq   :0         ;yes - ignore invalid keypress
  244.  
  245. :match                    ;we have a match...
  246.          iny              ;move to address
  247.          iny
  248.          tyx
  249.          jsr   (commands,x) ;call the handler
  250.  
  251.          rts              ;and return to main loop
  252.  
  253. commands                  ;table of command keys and addresses for handlers
  254.          dw    'P',Play
  255.          dw    'S',Stop
  256.          dw    'Q',Quit
  257.          dw    ' ',Pause
  258.          dw    '!',Status
  259.          dw    'Z',Reset
  260.          dw    $1b,Quit   ;escape key
  261.          dw    $a,Forward ;down arrow
  262.          dw    $b,Backward ;up arrow
  263.          dw    $15,SrchFwd ;right arrow
  264.          dw    $8,SrchBkd ;left arrow
  265.          dw    '?',Help
  266.          dw    '/',Help
  267. endcommands equ *
  268.  
  269. prompt
  270.          asc   0d'['
  271. TrackInd asc   '01] '     ;track number indicator
  272. Minutes  asc   '00:'
  273. Seconds  asc   '00 - Enter command or "?" for help: '00
  274.  
  275. *=============================================================================
  276. * set up for new disc (call on disc-switch events)
  277.  
  278. NewDisc
  279.          jsr   GDS        ;get device status and newDiscFlag (one last time!)
  280.          ~WriteCString #:nd
  281.          stz   newDiscFlag
  282.          stz   pauseFlag
  283.          lda   #'01'      ;start track indicator on track 1
  284.          sta   TrackInd
  285.          lda   #$0001
  286.          sta   TIBCD      ;store BCD value of track indicator
  287.          shortacc
  288.          lda   #$00
  289.          sta   statusData+5 ;get a type 0 TOC
  290.          longacc
  291.          lda   #$0002     ;get two bytes back
  292.          sta   DSrequest
  293.          lda   #ReadTOC   ;make this call
  294.          jsr   DoDStatus
  295.          shortacc
  296.          lda   buffer+1   ;get last track
  297.          longacc
  298.          jsr   BCD2Hex    ;convert to hex
  299. :noDisc  sta   maxTrack   ;save max track available
  300.          rts              ;and leave
  301.  
  302. :nd      asc   0d0d'(new disc)'0d00
  303.  
  304. *-----------------------------------------------------------------------------
  305. * play track CD
  306.  
  307. Play
  308.          ~WriteCString #playmsg
  309.  
  310. Play1
  311.          jsr   ZeroParamList ;zap old parameter list
  312.          shortacc
  313.          lda   TIBCD      ;get track (in BCD)
  314.          sta   statusData+2 ;store it in parm list
  315.          lda   #$80       ;we want a type 2 table of contents
  316.          sta   statusData+5
  317.          longacc
  318.          lda   #$0005     ;get five bytes back
  319.          sta   DSRequest
  320.          lda   #ReadTOC   ;find out info about this track
  321.          jsr   DoDStatus
  322.          lda   buffer
  323.          and   #%00000000_0000_1101 ;check out control field
  324.          cmp   #%00000000_0000_0100 ;is this a data track?
  325.          beq   :data      ;yes!
  326.  
  327.          jsr   ZeroParamList
  328.          shortacc
  329.          lda   maxTrack   ;stop track = last available
  330.                           ;to play only one track, use "lda TIBCD" instead
  331.          sta   controlData+5
  332.          lda   #$80       ;type 2: we're specifying a track number
  333.          sta   controlData+6
  334.          longacc
  335.  
  336.          lda   #AudioStop
  337.          jsr   DoDControl
  338.  
  339.          jsr   ZeroParamList ;zap old parameter list
  340.          shortacc
  341.          lda   #%00000000_0000_1001 ;play mode (stereo)
  342.          sta   controlData+3
  343.          lda   TIBCD      ;get track ind. value (in BCD)
  344.          sta   controlData+7 ;store track number
  345.          lda   #$80       ;type 2: we're specifying a track number
  346.          sta   controlData+8
  347.          longacc
  348.          lda   #AudioPlay
  349.          jsr   DoDControl
  350.          stz   pauseFlag  ;clear pause flag
  351. :exit    clc
  352.          rts
  353.  
  354. :data    ~WriteCString #:datatrack
  355.          bra   :exit
  356.  
  357. :datatrack asc |          - CAN'T PLAY; data track|00
  358. playmsg  asc   'Play'00
  359.  
  360. *-----------------------------------------------------------------------------
  361. * get status of drive
  362.  
  363. Status
  364.          ~WriteCString #:stat
  365.  
  366.          jsr   ZeroParamList ;zap old parameter list
  367.  
  368.          lda   #$0006     ;get six bytes from AudioStatus
  369.          sta   DSrequest
  370.          lda   #AudioStatus ;make this call
  371.          jsr   DoDStatus
  372.          shortacc
  373.          lda   buffer     ;get audio status
  374.          longacc
  375.          cmp   #5+1
  376.          bge   :bad
  377.          asl              ;*2 so offset into table is correct
  378.          tay
  379.          lda   #^:msgPtrs ;get current bank
  380.          pha              ;push high word
  381.          lda   :msgPtrs,y ;push low word
  382.          pha
  383.          _WriteCString    ;print string
  384.          clc
  385.          rts
  386.  
  387. :bad     ~WriteCString #:unk
  388.          clc
  389.          rts
  390.  
  391. :stat    asc   'Status'0d0d00
  392. :unk     asc   'Unknown audio status returned'0d00
  393. :msgPtrs
  394.          dw    :nowPlay   ;$00
  395.          dw    :pause     ;$01
  396.          dw    :muting    ;$02
  397.          dw    :playComp  ;$03
  398.          dw    :errPlay   ;$04
  399.          dw    :noPlay    ;$05
  400.  
  401. :nowPlay asc   'AudioPlay operation in progress'0d00
  402. :pause   asc   'Pause operation in progress'0d00
  403. :muting  asc   'Muting On operation in progress'0d00
  404. :playComp asc  'AudioPlay completion status'0d00
  405. :errPlay asc   'Error occurred during AudioPlay operation'0d00
  406. :noPlay  asc   'AudioPlay operation not requested'0d00
  407.  
  408. *-----------------------------------------------------------------------------
  409. * pause/resume playback
  410.  
  411. Pause
  412.          lda   #1         ;flip pauseFlag
  413.          sec
  414.          sbc   pauseFlag
  415.          sta   pauseFlag  ;what was the old status?
  416.          beq   :resume    ;...paused! so, resume
  417.          ~WriteCString #:pause
  418.          lda   #$10       ;hold pause
  419.          bra   :1
  420. :resume
  421.          ~WriteCString #:res
  422.          lda   #$00       ;release pause
  423. :1       shortacc
  424.          sta   controlData+2
  425.          longacc
  426.          lda   #AudioPause
  427.          jsr   DoDControl ;do it
  428.          clc
  429.          rts
  430.  
  431. :pause   asc   'Pause'00
  432. :res     asc   'Resume'00
  433.  
  434. *-----------------------------------------------------------------------------
  435. * stop audio playback
  436.  
  437. Stop
  438.          ~WriteCString #:stop
  439.          jsr   ZeroParamList ;zap old parameter list
  440.  
  441.          shortacc
  442.          lda   #0         ;stop on track zero (stop now)
  443.          sta   controlData+5
  444.          lda   #$80       ;type 2: we're specifying a track number
  445.          sta   controlData+6
  446.          longacc
  447.  
  448.          lda   #AudioStop
  449.          jsr   DoDControl
  450.  
  451.          lda   #1
  452.          sta   pauseFlag  ;set pause flag (allow resume)
  453.  
  454.          clc
  455.          rts
  456.  
  457. :stop    asc   'Stop'00
  458.  
  459. *-----------------------------------------------------------------------------
  460. * reset the drive
  461.  
  462. Reset                     ;
  463.          ~WriteCString #:reset
  464.          jsr   ZeroParamList ;zap old parameter list
  465.          lda   #ResetDevice
  466.          jsr   DoDControl
  467.          lda   #'01'      ;start track indicator on track 1
  468.          sta   TrackInd
  469.          lda   #$0001
  470.          sta   TIBCD      ;store BCD value of track indicator
  471.          jsr   Play1      ;start play on track 1, now
  472.          rts
  473.  
  474. :reset   asc   'Reset'00
  475.  
  476. *-----------------------------------------------------------------------------
  477. * search track
  478.  
  479. SrchFwd
  480.          ~WriteCString #ffwd
  481.          lda   #$00       ;$00 = fast forward
  482.          bra   x1
  483. SrchBkd
  484.          ~WriteCString #frwd
  485.          lda   #$40       ;$40 = fast rewind
  486.  
  487. x1       shortacc
  488.          pha              ;hold scan type
  489.          longacc
  490.  
  491.          jsr   ZeroParamList ;zap old parameter list
  492.          lda   #8         ;return eight bytes, please
  493.          sta   DSrequest
  494.          lda   #ReadQSubcode ;find out the current Q subcode info
  495.          jsr   DoDStatus
  496.  
  497.          jsr   ZeroParamList ;zap old parameter list
  498.  
  499.          shortacc
  500.          lda   buffer+6   ;get abs. minutes from ReadQSubcode call
  501.          sta   controlData+5 ;save it as start address for scan
  502.          lda   buffer+7   ;get abs. seconds
  503.          sta   controlData+6
  504.          lda   buffer+8   ;get abs. frames
  505.          sta   controlData+7
  506.  
  507.          pla              ;get scan type back
  508.          sta   controlData+2
  509.  
  510.          lda   #$40       ;address type 1 = abs. mins, secs, frames
  511.          sta   statusData+8
  512.          longacc
  513.  
  514.          lda   #AudioScan
  515.          jsr   DoDControl ;do it
  516.  
  517.          clc
  518.          rts
  519.  
  520. frwd     asc   'Fast Rewind'00
  521. ffwd     asc   'Fast Forward'00
  522.  
  523. *-----------------------------------------------------------------------------
  524. * zero out parameter table before filling it up
  525.  
  526. ZeroParamList
  527.          lda   #0
  528.          ldy   #10        ;zero out parameter list
  529. :1       sta   controlData,y
  530.          sta   statusData,y
  531.          dey
  532.          dey
  533.          bpl   :1
  534.          rts
  535.  
  536. *-----------------------------------------------------------------------------
  537. * make a DControl call - enter with control code in accumulator
  538.  
  539. DoDControl
  540.          sta   DCcode     ;store control code
  541.          shortacc
  542.          sta   controlData ;store it in start of the parameter list
  543.          longacc
  544.  
  545.          jsl   GSOS
  546.          dw    DControl   ;make GS/OS DControl call
  547.          adrl  :devParm
  548.  
  549.          jsr   GDS        ;get device status & set new disc flag, if necessary
  550.  
  551.          rts              ;and return with the call made
  552.  
  553. :devParm dw    5          ;parm list for the DControl call
  554. DCdevNum dw    0          ;fill in device number here
  555. DCcode   dw    0          ;control code
  556.          adrl  controlList ;pointer to buffer
  557.          dl    0          ;requestCount - unused
  558.          dl    0          ;transferCount
  559.  
  560. controlList dw 0          ;reserved
  561. controlData ds 12         ;12 bytes of data
  562.          adrl  buffer     ;pointer to buffer
  563. buffer   ds    20
  564.  
  565. *-----------------------------------------------------------------------------
  566. * make a DStatus call - enter with status code in accumulator
  567.  
  568. DoDStatus
  569.          sta   DScode     ;store control code
  570.          shortacc
  571.          sta   statusData ;store it in start of the parameter list
  572.          longacc
  573.  
  574.          jsl   GSOS
  575.          dw    DStatus    ;make GS/OS DStatus call
  576.          adrl  statParm
  577.  
  578.          jsr   GDS        ;get device status & set new disc flag, if necessary
  579.  
  580.          rts              ;and return with the call made
  581.  
  582. statParm dw    5          ;parm list for the DStatus call
  583. DSdevNum dw    0          ;fill in device number here
  584. DScode   dw    0          ;status code
  585.          adrl  statusList ;pointer to buffer
  586. DSrequest dl   0          ;requestCount
  587.          dl    0          ;transferCount
  588.  
  589. statusList dw  0          ;reserved
  590. statusData ds  12         ;12 bytes of data
  591.          adrl  buffer     ;pointer to buffer
  592.  
  593. *-----------------------------------------------------------------------------
  594. * move track indicator forward
  595.  
  596. Forward
  597.          ~WriteCString #:for
  598.  
  599.          jsr   GetTrackIndVal ;get val. of track indicator (not BCD)
  600.          cmp   maxTrack   ;are we on the last track of the disc?
  601.          blt   :no        ;not yet!
  602.          lda   #0         ;yes - wrap back to one
  603. :no      inc              ;move it up one
  604.          jsr   SetTrackIndVal ;set track indicator value
  605.          jsr   Play1      ;send the AudioPlay command
  606.          jsr   WaitOneSec ;and wait one second
  607.          clc
  608.          rts
  609.  
  610. :for     asc   'Forward'00
  611.  
  612. *-----------------------------------------------------------------------------
  613. * move track indicator back
  614.  
  615. Backward
  616.          ~WriteCString #:back
  617.          jsr   GetTrackIndVal ;get val. of track indicator (not BCD)
  618.          cmp   #1         ;are we on the first track?
  619.          beq   :first
  620.          dec              ;no - move back one track
  621.          cmp   maxTrack   ;larger than largest track?
  622.          bge   :first     ;yes - reset it to last track
  623.          bra   :go
  624. :first   lda   maxTrack   ;yes - wrap around to last track
  625. :go      jsr   SetTrackIndVal ;set new track indicator value
  626.          jsr   Play1      ;send the AudioPlay command
  627.          jsr   WaitOneSec ;and wait one second
  628.          clc
  629.          rts
  630.  
  631. :back    asc   'Backward'00
  632.  
  633. *-----------------------------------------------------------------------------
  634. * quit
  635.  
  636. Quit
  637.          sec              ;set carry to indicate that we want to leave
  638.          rts
  639.  
  640. *-----------------------------------------------------------------------------
  641. * get help
  642.  
  643. Help
  644.          ~WriteCString #helpInfo
  645.          clc
  646.          rts
  647.  
  648. helpInfo
  649.          asc   'Help'0d   ;print command
  650.          asc   0d'P = Play'
  651.          asc   0d'S = Stop'
  652.          asc   0d'! = Audio status'
  653.          asc   0d'Z = Zap (reset) drive'
  654.          asc   0d'? = This information'
  655.          asc   0d'Q = Quit'
  656.          asc   0d'Space bar to pause and resume playback.'
  657.          asc   0d'Up and down arrow keys to change track indicator.'
  658.          asc   0d'Left and right arrow keys to do inter-track search'
  659.          hex   0d00
  660.  
  661. *-----------------------------------------------------------------------------
  662. * wait one second
  663.  
  664. WaitOneSec                ;this is used after issuing an AudioPlay call, and
  665.                           ;before the following ReadQSubcode. Occasionally,
  666.                           ;the drive can't synchronize the results of the
  667.                           ;DStatus with the actual current Q Subcode. This
  668.                           ;means that you may go from playing track one to
  669.                           ;track two, and while the disc is seeking on (and
  670.                           ;playing) track 2, 00:00, the ReadQSubcode call will
  671.                           ;return track 1, and the last second of track one
  672.                           ;(for example, 02:58, if track one is that long).
  673.  
  674.                           ;Waiting for one second allows the drive to get it's
  675.                           ;values straight.
  676.  
  677.          ~GetTick         ;get the starting tick count
  678.  
  679.          pla              ;get low word of starting tick count
  680.          clc
  681.          adc   #60        ;wait for 60 ticks (one second)
  682.          sta   endTicks
  683.          pla              ;get high word
  684.          adc   #0         ;...add zero to handle any carry
  685.          sta   endTicks+2
  686.  
  687. :loop                     ;now, wait until we're
  688.          ~GetTick         ;get current tick count
  689.  
  690.          pla              ;get value
  691.          plx
  692.          cmp   endTicks   ;does low word match?
  693.          bne   :loop      ;no, keep waiting
  694.          cpx   endTicks+2 ;yes - how about high word?
  695.          bne   :loop      ;no, keep waiting
  696.  
  697.          rts              ;yes; a second has passed. leave.
  698.  
  699. *-----------------------------------------------------------------------------
  700. * get track indicator value (returns value in hex)
  701.  
  702. GetTrackIndVal
  703.          lda   TrackInd   ;get track indicator ($3233)
  704.          xba              ;flip it ($3332)
  705.          and   #$0f0f     ;get rid of ASCII parts ($0302)
  706.          pha              ;hold that for a moment ($0302)
  707.          and   #$00ff     ;zap high word ($0002)
  708.          sta   temp       ;store it ($0002)
  709.          pla              ;get old value back ($0302)
  710.          xba              ;flip it ($0203)
  711.          shortacc
  712.          asl              ;promote low nibble ($03 -> $30)
  713.          asl
  714.          asl
  715.          asl
  716.          longacc
  717.          and   #$00ff     ;get rid of residue in high word
  718.          ora   temp       ;now we should have $0032
  719.  
  720.          sta   TIBCD      ;store BCD value of track indicator
  721.  
  722. * now change the BCD value into hex
  723.          jsr   BCD2Hex
  724.          rts
  725.  
  726. *-----------------------------------------------------------------------------
  727. * convert BCD value into hex value
  728.  
  729. BCD2Hex
  730.          ldx   #0         ;start with zero
  731.          sed              ;turn decimal mode on
  732. :1       inx
  733.          sec              ;bump it down one
  734.          sbc   #1
  735.          bne   :1         ;keep going!
  736.          cld
  737.  
  738.          txa              ;returns with hex value in accum
  739.          rts
  740.  
  741. *-----------------------------------------------------------------------------
  742. * set track indicator value (enter with hex value - exits with BCD value)
  743.  
  744. SetTrackIndVal
  745.                           ;first, change value into BCD
  746.          tax
  747.          lda   #0
  748.          sed              ;turn decimal mode on
  749. :1       clc              ;bump it down one
  750.          adc   #1
  751.          dex
  752.          bne   :1         ;keep going!
  753.          cld
  754.  
  755.          sta   TIBCD      ;store BCD value of track indicator
  756.  
  757.          rts
  758.  
  759. BCD2ASCII
  760.          pha              ;hold original ($0012)
  761.          and   #$000f     ;isolate low byte ($0002)
  762.          ora   #$0030     ;make it ASCII ($0032)
  763.          sta   temp       ;hold it for now ($0032)
  764.          pla              ;get original back ($0012)
  765.          and   #$00f0     ;isolate the high nibble of the low byte ($0010)
  766.          asl              ;promote it to low nibble of high byte ($0100)
  767.          asl
  768.          asl
  769.          asl
  770.          ora   #$3000     ;make it ASCII ($3100)
  771.          ora   temp       ;add on low byte ($3132 = '12')
  772.          rts              ;and go with it
  773.  
  774. *-----------------------------------------------------------------------------
  775. * find the CD-ROM drive
  776.  
  777. FindCDRom
  778.          lda   CDROMDev   ;have we found it before?
  779.          bne   :leave     ;yes - leave now
  780.  
  781. :look                     ;start looking for drive
  782.          jsl   GSOS
  783.          dw    DInfo      ;make GS/OS DInfo call
  784.          adrl  :devParm
  785.          bcs   :err       ;leave if error
  786.  
  787.          lda   devID      ;get device ID
  788.          cmp   #$0007     ;is is a SCSI CD ROM device?
  789.          beq   :found     ;yes - found it
  790.  
  791.          inc   devNum     ;no - move to next device
  792.          bra   :look      ;and keep looking
  793.  
  794. :found   lda   devNum
  795.          sta   CDROMDev
  796.          sta   DCdevNum   ;store device number for all control calls
  797.          sta   DSdevNum   ;store device number for all status calls
  798. :leave   clc              ;found it
  799.          rts
  800.  
  801. :none    ~WriteCString #:noCDRom
  802. :1       jsr   getKey
  803.          sec              ;none found!
  804.          rts
  805.  
  806. :err     cmp   #$11       ;error $11 - invalid device number?
  807.          beq   :none      ;yes - no CD-ROM drive found!
  808.          ~WriteCString #:error ;no - some other weird error
  809.          bra   :1
  810.  
  811. :error   asc   0d'GS/OS error on DInfo call. Press any key to quit. '0700
  812. :noCDRom asc   0d'No CD-ROM drive found. Press any key to quit. '0700
  813.  
  814. :devParm dw    8          ;8 parameters
  815. devNum   dw    1          ;device number - start with one
  816.          adrl  nameBuffer ;pointer to buffer for device name
  817.          dw    0          ;characteristics
  818.          dl    0          ;totalBlocks
  819.          dw    0          ;slotNum
  820.          dw    0          ;unitNum
  821.          dw    0          ;version
  822. devID    dw    0          ;device ID: $0007 = SCSI CD ROM
  823.  
  824. nameBuffer dw  31         ;max length
  825.          ds    33         ;storage for device name
  826.  
  827. *-----------------------------------------------------------------------------
  828. * get a keypress, returned in the accum
  829.  
  830. getKey
  831.          ~ReadChar #0     ;don't echo it
  832.          pla
  833.          and   #$007f     ;isolate low byte
  834.          rts
  835.  
  836. *-----------------------------------------------------------------------------
  837. * start up appropriate tools
  838.  
  839. Start                     ;get the right tools up
  840.          stz   suTT       ;zap flag: assume they're already up
  841.          ~TextStatus      ;get the status of the text tools
  842.          pla
  843.          bcs   :startEm   ;start them!
  844.          bne   :alreadyUp ;if they're already up, don't re-start them
  845.  
  846. :startEm _TextStartUp     ;(unnecessary if we came from the CDA menu)
  847.          inc   suTT       ;set flag so we know to shut them down, too
  848.          bra   :cont
  849.  
  850. :alreadyUp                ;they're already up, so....
  851.          ~GetInputDevice  ;get the current input device
  852.          PullLong iPtrOrSlot
  853.          PullWord iDevType
  854.          ~GetInGlobals    ;get current input device globals
  855.          PullWord iORmsk
  856.          PullWord iANDmsk
  857.          ~GetOutputDevice ;get the current output device
  858.          PullLong oPtrOrSlot
  859.          PullWord oDevType
  860.          ~GetOutGlobals   ;get the current output device globals
  861.          PullWord oORmsk
  862.          PullWord oANDmsk
  863.  
  864. :cont
  865.          ~SetInputDevice #$0000;#$00000003 ;basic driver - slot 3
  866.          ~SetOutputDevice #$0000;#$00000003 ;same as above
  867.          ~SetInGlobals #$00ff;#$0080 ;AND mask, OR mask
  868.          ~SetOutGlobals #$00ff;#$0080 ;same as above
  869.          bra   InitTDevs  ;init the text devices and leave
  870.  
  871. RestoreTDevs              ;restore the text devices to what they were before
  872.          ~SetInGlobals iANDmsk;iORmsk ;restore AND mask and OR mask
  873.          ~SetOutGlobals oANDmsk;oORmsk ;same as above
  874.          ~SetInputDevice iDevType;iPtrOrSlot ;restore driver type and location
  875.          ~SetOutputDevice oDevType;oPtrOrSlot ;same as above
  876.                           ;and leave by re-initializing the devices
  877.  
  878. InitTDevs
  879.          ~InitTextDev #$0000 ;get input device ready
  880.          ~InitTextDev #$0001 ;get output device ready
  881.          rts
  882.  
  883. ******************************************************************************
  884. * data area
  885.  
  886. TIBCD    dw    0          ;track indicator (BCD value)
  887. CDROMDev dw    0          ;CD-ROM device number
  888.  
  889. oldDP    dw    0          ;old direct-page register value
  890.